﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Resources;
using System.Windows.Input;
using System.Collections.ObjectModel;
using System.Windows.Media;
using System.Runtime.Serialization;
using lutianqi.Model;
using lutianqi.Helpers;
using lutianqi.DAL;
using System.Runtime.Serialization.Json;
using System.Threading;

namespace lutianqi
{
    public class MainViewModel : INotifyPropertyChanged
    {
        public MainViewModel()
        {
            this.WeatherInfo = new WeatherInfoConverted();
        }

        //设置Panorama的默认选项
        public int? selectIndex;

        private bool _IsLoading;
        public bool IsLoading
        {
            get
            {
                return _IsLoading;
            }
            set
            {
                if (value != _IsLoading)
                {
                    _IsLoading = value;
                    NotifyPropertyChanged("IsLoading");
                }
            }
        }
        private Visibility _WeatherInfoPanelVisibility;
        public Visibility WeatherInfoPanelVisibility
        {
            get
            {
                return _WeatherInfoPanelVisibility;
            }
            set
            {
                if (value != _WeatherInfoPanelVisibility)
                {
                    _WeatherInfoPanelVisibility = value;
                    NotifyPropertyChanged("WeatherInfoPanelVisibility");
                }
            }
        }
        //记录MainViewModel的数据是否已初始化
        public bool IsDataLoaded
        {
            get;
            private set;
        }
        //存储从数据缓存服务器返回的天气信息
        private WeatherInfoConverted _weatherinfo;
        public WeatherInfoConverted WeatherInfo
        {
            get
            {
                return _weatherinfo;
            }
            set
            {
                if (value != _weatherinfo)
                {
                    _weatherinfo = value;
                    NotifyPropertyChanged("WeatherInfo");
                }
            }
        }
        //存储用户设定的主题名称（出于激活/使用状态的主题）
        private string _CurrentTheme;
        public string CurrentTheme
        {
            get
            {
                return _CurrentTheme;
            }
            set
            {
                if (value != _CurrentTheme)
                {
                    _CurrentTheme = value;
                    NotifyPropertyChanged("CurrentTheme");
                    NotifyPropertyChanged("WeatherInfo");//即时变更主题
                }
            }
        }

        private ObservableCollection<ThemeConfig> _ThemeConfigList;
        public ObservableCollection<ThemeConfig> ThemeConfigList
        {
            get
            {
                if (_ThemeConfigList == null)
                    _ThemeConfigList = new ObservableCollection<ThemeConfig>();
                return _ThemeConfigList;
            }
            set
            {
                if (value != _ThemeConfigList)
                {
                    _ThemeConfigList = value;
                    NotifyPropertyChanged("ThemeConfigList");
                }
            }
        }
        private ObservableCollection<FavoriteItem> _FavoriteItemList;
        public ObservableCollection<FavoriteItem> FavoriteItemList
        {
            get
            {
                if (_FavoriteItemList == null)
                    _FavoriteItemList = new ObservableCollection<FavoriteItem>();
                return _FavoriteItemList;
            }
            set
            {
                if (value != _FavoriteItemList)
                {
                    _FavoriteItemList = value;
                    NotifyPropertyChanged("FavoriteItemList");
                }
            }
        }

        //存储城市名和城市编号映射关系的List
        public List<CityCodeMapping> CityList;
        //LongListSelector控件的数据源
        private IEnumerable<GroupingLayer<string, CityCodeMapping>> _longlistitems;
        public IEnumerable<GroupingLayer<string, CityCodeMapping>> LongListItems
        {
            get
            {
                return _longlistitems;
            }
            set
            {
                if (value != _longlistitems)
                {
                    _longlistitems = value;
                    NotifyPropertyChanged("LongListItems");
                }
            }
        }

        public int CurrentPanoramaItemSelectIndex = 0;
        private ICommand _SetCurrentPanoramaItemNameCommand;
        public ICommand SetCurrentPanoramaItemNameCommand
        {
            get
            {
                if (_SetCurrentPanoramaItemNameCommand == null) _SetCurrentPanoramaItemNameCommand = new DelegateCommand(SetCurrentPanoramaItemSelectIndex, CanExecute);
                return _SetCurrentPanoramaItemNameCommand;
            }
        }

        private ICommand _GetSpecificWeatherInfoCommand;
        public ICommand GetSpecificWeatherInfoCommand
        {
            get
            {
                if (_GetSpecificWeatherInfoCommand == null) _GetSpecificWeatherInfoCommand = new DelegateCommand(GetSpecificWeatherInfo, CanExecute);
                return _GetSpecificWeatherInfoCommand;
            }
        }

        private ICommand _SetThemeCommand;
        public ICommand SetThemeCommand
        {
            get
            {
                if (_SetThemeCommand == null) _SetThemeCommand = new DelegateCommand(SetTheme, CanExecute);
                return _SetThemeCommand;
            }
        }

        private ICommand _SetFavoriteColorCommand;
        public ICommand SetFavoriteColorCommand
        {
            get
            {
                if (_SetFavoriteColorCommand == null) _SetFavoriteColorCommand = new DelegateCommand(SetFavoriteColor, CanExecute);
                return _SetFavoriteColorCommand;
            }
        }

        private ICommand _DelFavCommand;
        public ICommand DelFavCommand
        {
            get
            {
                if (_DelFavCommand == null) _DelFavCommand = new DelegateCommand(DelFav, CanExecute);
                return _DelFavCommand;
            }
        }

        private ICommand _AddFavCommand;
        public ICommand AddFavCommand
        {
            get
            {
                if (_AddFavCommand == null) _AddFavCommand = new DelegateCommand(AddFav, CanExecute);
                return _AddFavCommand;
            }
        }

        //初始化数据
        public void LoadData()
        {
            XMLProcessor.InitialConfig();//初始化独立存储中的设定档
            CurrentTheme = XMLProcessor.ReadCurrentTheme();//读取用户设定的主题名称（出于激活/使用状态的主题）
            InitialThemeList();
            InitialFavoriteItemList();
            //读取城市名与城市代码的映射信息
            CityList = CityCodeMappingProcessor.GetCityCodeMappingList();
            //处理CityList（根据Region字段分组）以产生适合LongListSelector使用的数据源
            LongListItems = from c in CityList group c by c.Region into n select new GroupingLayer<string, CityCodeMapping>(n);
            this.IsDataLoaded = true;
        }

        public void GetWeatherInfoByCityID(string cityCode)
        {
            string requestUri = string.Format("http://m.weather.com.cn/data/{0}.html", cityCode == "" ? "101230201" : cityCode);

            Deployment.Current.Dispatcher.BeginInvoke(() =>{
                    GetWeather(requestUri,(result) =>{
                        if (null != result.cityid){
                            WeatherInfoPanelVisibility = Visibility.Visible;
                            this.WeatherInfo = result;
                            IsLoading = false;
                        }
                        else{
                            this.WeatherInfo = new WeatherInfoConverted();
                            IsLoading = false;
                            MessageBox.Show("抱歉,不能获取到天气数据!");
                        }
                    },
                    (exception) => { 
                        MessageBox.Show(exception.Message); 
                    },null);
                });
        }

        private void GetSpecificWeatherInfo(object parameter)
        {
            if (parameter != null)
            {
                WeatherInfo = new WeatherInfoConverted();
                GetWeatherInfoByCityID(parameter.ToString());
                //保存当前选择的城市,下次打开时直接用这个城市代码去获取天气信息
                ValueHelper.SetVaule("CityCode", parameter);
                IsLoading = true;
                WeatherInfoPanelVisibility = Visibility.Collapsed;
            }
        }

        private void SetCurrentPanoramaItemSelectIndex(object parameter)
        {
            if (parameter != null)
            {
                this.CurrentPanoramaItemSelectIndex = (int)parameter;
            }
        }

        private void SetTheme(object parameter)
        {
            if (parameter != null && parameter.ToString() != string.Empty)
            {
                XMLProcessor.SetCurrentTheme(parameter.ToString());
                CurrentTheme = XMLProcessor.ReadCurrentTheme();
                InitialThemeList();
            }
        }

        private void SetFavoriteColor(object parameter)
        {
            if (parameter != null && parameter.ToString() != string.Empty)
            {
                XMLProcessor.SetFavoriteColor(parameter.ToString());
                InitialFavoriteItemList();
            }
        }

        private void DelFav(object parameter)
        {
            if (parameter != null && parameter.ToString() != string.Empty)
            {
                XMLProcessor.DelFav(parameter.ToString());
                InitialFavoriteItemList();
            }
        }

        private void AddFav(object parameter)
        {
            if (parameter != null && parameter.ToString() != string.Empty)
            {
                var cityname = from p in App.ViewModel.CityList where p.CityCode == parameter.ToString() select p.CityName;
                XMLProcessor.AddFav(parameter.ToString(), cityname.First());
                InitialFavoriteItemList();
            }
        }

        private bool CanExecute(object parameter)
        {
            return true;
        }

        private void InitialThemeList()
        {
            ThemeConfigList.Clear();
            foreach (string tpstr in XMLProcessor.GetThemeList())
            {
                ThemeConfigList.Add(new ThemeConfig() { ThemeName = tpstr });
            }
        }

        private void InitialFavoriteItemList()
        {
            FavoriteItemList.Clear();
            foreach (FavoriteItem tp in XMLProcessor.GetFavoriteItemList())
            {
                FavoriteItemList.Add(new FavoriteItem() { CityCode = tp.CityCode, CityName = tp.CityName, bgColor = tp.bgColor });
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName)
        {
            if (null != PropertyChanged)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        void GetWeather(string uri, Action<WeatherInfoConverted> onGetWeatherInfoCompleted = null, Action<Exception> onError = null, Action onFinally = null)
        {
            IsLoading = true;
            WeatherInfoPanelVisibility = Visibility.Collapsed;
            WebClient webClient = new WebClient();
            webClient.OpenReadCompleted +=
               delegate(object sender, OpenReadCompletedEventArgs e)
               {
                   try
                   {
                       if (e.Error != null)
                       {
                           if (onError != null)
                           {
                               onError(e.Error);
                           }
                           return;
                       }

                       Stream stream = e.Result;
                       DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Weather));
                       Weather weather = (Weather)serializer.ReadObject(stream);
                       WeatherInfoConverted weatherInfo = WeatherDAL.GetConvertedWeatherInfo(weather);

                       if (onGetWeatherInfoCompleted != null)
                       {
                           onGetWeatherInfoCompleted(weatherInfo);
                       }
                   }
                   finally
                   {
                       if (onFinally != null)
                       {
                           onFinally();
                       }
                   }
               };

            webClient.OpenReadAsync(new Uri(uri, UriKind.Absolute));
        }
    }
}